/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#include"ImageLayerComposite.h"#include"CompositableHost.h" // for CompositableHost#include"Layers.h" // for WriteSnapshotToDumpFile, etc#include"gfx2DGlue.h" // for ToFilter#include"gfxEnv.h" // for gfxEnv#include"gfxRect.h" // for gfxRect#include"mozilla/Assertions.h" // for MOZ_ASSERT, etc#include"mozilla/gfx/Matrix.h" // for Matrix4x4#include"mozilla/gfx/Point.h" // for IntSize, Point#include"mozilla/gfx/Rect.h" // for Rect#include"mozilla/layers/Compositor.h" // for Compositor#include"mozilla/layers/Effects.h" // for EffectChain#include"mozilla/layers/ImageHost.h" // for ImageHost#include"mozilla/layers/TextureHost.h" // for TextureHost, etc#include"mozilla/mozalloc.h" // for operator delete#include"nsAString.h"#include"mozilla/RefPtr.h" // for nsRefPtr#include"nsDebug.h" // for NS_ASSERTION#include"nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc#include"nsString.h" // for nsAutoCStringnamespacemozilla{namespacelayers{usingnamespacemozilla::gfx;ImageLayerComposite::ImageLayerComposite(LayerManagerComposite*aManager):ImageLayer(aManager,nullptr),LayerComposite(aManager),mImageHost(nullptr){MOZ_COUNT_CTOR(ImageLayerComposite);mImplData=static_cast<LayerComposite*>(this);}ImageLayerComposite::~ImageLayerComposite(){MOZ_COUNT_DTOR(ImageLayerComposite);MOZ_ASSERT(mDestroyed);CleanupResources();}boolImageLayerComposite::SetCompositableHost(CompositableHost*aHost){switch(aHost->GetType()){caseCompositableType::IMAGE:mImageHost=static_cast<ImageHost*>(aHost);returntrue;default:returnfalse;}}voidImageLayerComposite::Disconnect(){Destroy();}Layer*ImageLayerComposite::GetLayer(){returnthis;}voidImageLayerComposite::SetLayerManager(HostLayerManager*aManager){LayerComposite::SetLayerManager(aManager);mManager=aManager;if(mImageHost){mImageHost->SetTextureSourceProvider(mCompositor);}}voidImageLayerComposite::RenderLayer(constIntRect&aClipRect,constMaybe<gfx::Polygon>&aGeometry){if(!mImageHost||!mImageHost->IsAttached()){return;}#ifdef MOZ_DUMP_PAINTINGif(gfxEnv::DumpCompositorTextures()){RefPtr<gfx::DataSourceSurface>surf=mImageHost->GetAsSurface();if(surf){WriteSnapshotToDumpFile(this,surf);}}#endifmCompositor->MakeCurrent();RenderWithAllMasks(this,mCompositor,aClipRect,[&](EffectChain&effectChain,constIntRect&clipRect){mImageHost->SetTextureSourceProvider(mCompositor);mImageHost->Composite(mCompositor,this,effectChain,GetEffectiveOpacity(),GetEffectiveTransformForBuffer(),GetSamplingFilter(),clipRect);});mImageHost->BumpFlashCounter();}voidImageLayerComposite::ComputeEffectiveTransforms(constgfx::Matrix4x4&aTransformToSurface){gfx::Matrix4x4local=GetLocalTransform();// Snap image edges to pixel boundariesgfxRectsourceRect(0,0,0,0);if(mImageHost&&mImageHost->IsAttached()){IntSizesize=mImageHost->GetImageSize();sourceRect.SizeTo(size.width,size.height);}// Snap our local transform first, and snap the inherited transform as well.// This makes our snapping equivalent to what would happen if our content// was drawn into a PaintedLayer (gfxContext would snap using the local// transform, then we'd snap again when compositing the PaintedLayer).mEffectiveTransform=SnapTransform(local,sourceRect,nullptr)*SnapTransformTranslation(aTransformToSurface,nullptr);if(mScaleMode!=ScaleMode::SCALE_NONE&&sourceRect.width!=0.0&&sourceRect.height!=0.0){NS_ASSERTION(mScaleMode==ScaleMode::STRETCH,"No other scalemodes than stretch and none supported yet.");local.PreScale(mScaleToSize.width/sourceRect.width,mScaleToSize.height/sourceRect.height,1.0);mEffectiveTransformForBuffer=SnapTransform(local,sourceRect,nullptr)*SnapTransformTranslation(aTransformToSurface,nullptr);}else{mEffectiveTransformForBuffer=mEffectiveTransform;}ComputeEffectiveTransformForMaskLayers(aTransformToSurface);}boolImageLayerComposite::IsOpaque(){if(!mImageHost||!mImageHost->IsAttached()){returnfalse;}if(mScaleMode==ScaleMode::STRETCH){returnmImageHost->IsOpaque();}returnfalse;}nsIntRegionImageLayerComposite::GetFullyRenderedRegion(){if(!mImageHost||!mImageHost->IsAttached()){returnGetShadowVisibleRegion().ToUnknownRegion();}if(mScaleMode==ScaleMode::STRETCH){nsIntRegionshadowVisibleRegion;shadowVisibleRegion.And(GetShadowVisibleRegion().ToUnknownRegion(),nsIntRegion(gfx::IntRect(0,0,mScaleToSize.width,mScaleToSize.height)));returnshadowVisibleRegion;}returnGetShadowVisibleRegion().ToUnknownRegion();}CompositableHost*ImageLayerComposite::GetCompositableHost(){if(mImageHost&&mImageHost->IsAttached()){returnmImageHost.get();}returnnullptr;}voidImageLayerComposite::CleanupResources(){if(mImageHost){mImageHost->CleanupResources();mImageHost->Detach(this);}mImageHost=nullptr;}gfx::SamplingFilterImageLayerComposite::GetSamplingFilter(){returnmSamplingFilter;}voidImageLayerComposite::GenEffectChain(EffectChain&aEffect){aEffect.mLayerRef=this;aEffect.mPrimaryEffect=mImageHost->GenEffect(GetSamplingFilter());}voidImageLayerComposite::PrintInfo(std::stringstream&aStream,constchar*aPrefix){ImageLayer::PrintInfo(aStream,aPrefix);if(mImageHost&&mImageHost->IsAttached()){aStream<<"\n";nsAutoCStringpfx(aPrefix);pfx+=" ";mImageHost->PrintInfo(aStream,pfx.get());}}}// namespace layers}// namespace mozilla